// Lindsay Gilmour
// Adam Lusch
// Dan Niceswanger
//
// Computer Graphics Project 2:
// Teapot racing!

#include <GL/glut.h>

#include <Box2D.h>
#include "PhysicsWorld.h"


namespace
{
	int32 width = 800;
	int32 height = 600;
	float32 framePeriod = 1000.0 / 60.0;
	float32 timeStep = 1.0 / 60.0;
	int32 iterations = 10;
	PhysicsWorld pworld;
	int32 keys[256];
	
	// Lighting parameters
	GLfloat ambientLight0[] = {0.5f, 0.5f, 0.5f, 1.0f};
	GLfloat diffuseLight0[] = {1.0f, 1.0f, 1.0f, 1.0f};
	GLfloat specular0[] = {1.0f, 1.0f, 1.0f, 1.0f};
}

void resize(int32 w, int32 h)
{
	width = w;
	height = h;

	// Setup viewport same size as window minus its borders
	glViewport(0, 0, w, h);

	// change to the PROJECTION matrix, load the Identity so we can
	// setup the matrix for projection into a resized window
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// pick camera lens
	gluPerspective(45.0, (GLdouble)w / (GLdouble)h, 0.1, 5000.0);

	// aim camera so we can draw stuff later
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	// Initial view of the teapot
	gluLookAt(-1.5, 0.75, 0.0, 0.0, 0.4, 0.0, 0.0, 1.0, 0.0);
}

// This is used to control the frame rate (60Hz).
void timer(int)
{
	glutPostRedisplay();
	glutTimerFunc((int)framePeriod, timer, 0);
}

void simulationLoop()
{	 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();
	
	pworld.step(timeStep, iterations, keys);
	
	glPopMatrix();
	
	glFinish();
	glutSwapBuffers();
}

// change the keyState to include the
// direction of the pressed key
void pressArrowKey(int k, int, int)
{
	switch (k)
	{
		case GLUT_KEY_LEFT:
		case GLUT_KEY_RIGHT:
		case GLUT_KEY_UP:
		case GLUT_KEY_DOWN:
			keys[k] = 1;
			break;
	}
}

void releaseArrowKey(int k, int, int)
{
	switch (k)
	{
		case GLUT_KEY_LEFT:
		case GLUT_KEY_RIGHT:
		case GLUT_KEY_UP:
		case GLUT_KEY_DOWN:
			keys[k] = 0;
			break;
	}
}

void key(unsigned char k, int, int)
{
	switch (k)
	{
		case ' ':
			keys[k] = 1;
			break;
	}
}

void keyUp(unsigned char k, int, int)
{
	switch (k)
	{
		case ' ':
			keys[k] = 0;
			break;
	}
}

int main(int argc, char** argv)
{
	time_t seed = time(0);
	srand(seed);
	//cout << "Seeding with " << seed << endl;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(width, height);
	glutCreateWindow("Teapot Racing!");

	glutReshapeFunc(resize);
	glutDisplayFunc(simulationLoop);
	glutTimerFunc((int)framePeriod, timer, 0);
	glutSpecialFunc(pressArrowKey);
	glutSpecialUpFunc(releaseArrowKey);
	glutKeyboardFunc(key);
	glutKeyboardUpFunc(keyUp);
	
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_NORMALIZE);
	glShadeModel(GL_SMOOTH);

	glEnable(GL_LIGHTING);
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight0);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
	glEnable(GL_LIGHT0);

	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);
	
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_LINE_SMOOTH);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
	
	glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	
	glClearColor(0.54, 0.82, 0.98, 1.0);

	pworld.init();
	
	pworld.splashScreen();
	
	//pworld.startGame();

	glutMainLoop();

	return 0;
}
